home *** CD-ROM | disk | FTP | other *** search
- /* NLProc.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "NLProc.h"
- #include "FastFixedPoint.h"
- #include "SampleConsts.h"
- #include "NonlinearProcSpec.h"
- #include "Memory.h"
- #include "WaveTableObject.h"
- #include "AlgoWaveTableObject.h"
- #include "FloatingPoint.h"
- #include "WaveIndexUtility.h"
-
-
- struct NLProcRec
- {
- /* number of frames per table */
- long FramesPerTable;
- /* number of tables */
- long NumberOfTables;
- /* raw wave table data array */
- void** WaveTableMatrix;
- /* function for indexing the wave table */
- signed long (*WaveIndexer)(float Phase, FastFixedType TableIndex,
- long NumTables, long Frames, void** Matrix);
- /* stereo flag */
- MyBoolean StereoFlag;
- /* number of bits */
- NumBitsType NumBits;
- /* reciprocal of volume scaling factor */
- float InverseVolume;
-
- /* state parameters */
- float CurrentInputScaling;
- float CurrentOutputScaling;
- FastFixedType CurrentWaveTableIndex;
-
- /* control parameters */
- float InputScaling;
- float InputAccent1;
- float InputAccent2;
- float InputAccent3;
- float InputAccent4;
- float OutputScaling;
- float OutputAccent1;
- float OutputAccent2;
- float OutputAccent3;
- float OutputAccent4;
- float WaveTableIndex;
- float IndexAccent1;
- float IndexAccent2;
- float IndexAccent3;
- float IndexAccent4;
-
- /* free list link */
- NLProcRec* Next;
- };
-
-
- static NLProcRec* NLProcFreeList = NIL;
-
-
- /* flush free list elements */
- void FlushCachedNLProcStuff(void)
- {
- while (NLProcFreeList != NIL)
- {
- NLProcRec* Temp;
-
- Temp = NLProcFreeList;
- NLProcFreeList = NLProcFreeList->Next;
- ReleasePtr((char*)Temp);
- }
- }
-
-
- /* create a new nonlinear processor */
- NLProcRec* NewNLProcProcessor(struct NonlinProcSpecRec* Template,
- MyBoolean StereoFlag, float InverseVolume)
- {
- NLProcRec* NLProc;
-
- CheckPtrExistence(Template);
- if (NLProcFreeList != NIL)
- {
- NLProc = NLProcFreeList;
- NLProcFreeList = NLProcFreeList->Next;
- }
- else
- {
- NLProc = (NLProcRec*)AllocPtrCanFail(sizeof(NLProcRec),"NLProcRec");
- if (NLProc == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- }
- NLProc->InverseVolume = InverseVolume;
- switch (GetNLProcSpecWaveType(Template))
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewNLProcProcessor: invalid nlproc wavetable type"));
- break;
- case eNLDataWaveTable:
- {
- WaveTableObjectRec* DataWaveTable;
- long Index;
-
- DataWaveTable = GetNLProcSpecDataWaveTable(Template);
- CheckPtrExistence(DataWaveTable);
- NLProc->NumberOfTables = WaveTableObjectGetNumTables(DataWaveTable);
- NLProc->FramesPerTable = WaveTableObjectEntriesPerTable(DataWaveTable);
- NLProc->NumBits = WaveTableObjectGetNumBits(DataWaveTable);
- NLProc->WaveTableMatrix = (void**)AllocPtrCanFail(sizeof(void*)
- * NLProc->NumberOfTables,"Wave table vector");
- if (NLProc->WaveTableMatrix == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)NLProc);
- goto FailurePoint1;
- }
- for (Index = 0; Index < NLProc->NumberOfTables; Index += 1)
- {
- PRNGCHK(NLProc->WaveTableMatrix,&(((void**)(NLProc->WaveTableMatrix))[
- Index]),sizeof(((void**)(NLProc->WaveTableMatrix))[Index]));
- ((void**)(NLProc->WaveTableMatrix))[Index]
- = WaveTableObjectGetRawSlice(DataWaveTable,Index);
- }
- }
- break;
- case eNLAlgoWaveTable:
- {
- AlgoWaveTableObjectRec* AlgoWaveTable;
- long Index;
-
- AlgoWaveTable = GetNLProcSpecAlgoWaveTable(Template);
- CheckPtrExistence(AlgoWaveTable);
- NLProc->NumberOfTables = AlgoWaveTableObjectGetNumTables(AlgoWaveTable);
- NLProc->FramesPerTable = AlgoWaveTableObjectGetNumFrames(AlgoWaveTable);
- NLProc->NumBits = AlgoWaveTableObjectGetNumBits(AlgoWaveTable);
- NLProc->WaveTableMatrix = (void**)AllocPtrCanFail(sizeof(void*)
- * NLProc->NumberOfTables,"Wave table vector");
- if (NLProc->WaveTableMatrix == NIL)
- {
- FailurePoint2a:
- goto FailurePoint2;
- }
- for (Index = 0; Index < NLProc->NumberOfTables; Index += 1)
- {
- PRNGCHK(NLProc->WaveTableMatrix,&(((void**)(NLProc->WaveTableMatrix))[
- Index]),sizeof(((void**)(NLProc->WaveTableMatrix))[Index]));
- ((void**)(NLProc->WaveTableMatrix))[Index]
- = AlgoWaveTableObjectGetRawSlice(AlgoWaveTable,Index);
- }
- }
- break;
- }
- switch (NLProc->NumBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewLFOGenerator: bad num bits"));
- break;
- case eSample8bit:
- NLProc->WaveIndexer = (signed long (*)(float,
- FastFixedType,long,long,void**))&WaveTable8Bit;
- break;
- case eSample16bit:
- NLProc->WaveIndexer = (signed long (*)(float,
- FastFixedType,long,long,void**))&WaveTable16Bit;
- break;
- }
- NLProc->StereoFlag = StereoFlag;
- NLProc->InputScaling = GetNLProcInputScaling(Template);
- NLProc->InputAccent1 = GetNLProcInputAccent1(Template);
- NLProc->InputAccent2 = GetNLProcInputAccent2(Template);
- NLProc->InputAccent3 = GetNLProcInputAccent3(Template);
- NLProc->InputAccent4 = GetNLProcInputAccent4(Template);
- NLProc->OutputScaling = GetNLProcOutputScaling(Template);
- NLProc->OutputAccent1 = GetNLProcOutputAccent1(Template);
- NLProc->OutputAccent2 = GetNLProcOutputAccent2(Template);
- NLProc->OutputAccent3 = GetNLProcOutputAccent3(Template);
- NLProc->OutputAccent4 = GetNLProcOutputAccent4(Template);
- NLProc->WaveTableIndex = GetNLProcWaveTableIndex(Template);
- NLProc->IndexAccent1 = GetNLProcIndexAccent1(Template);
- NLProc->IndexAccent2 = GetNLProcIndexAccent2(Template);
- NLProc->IndexAccent3 = GetNLProcIndexAccent3(Template);
- NLProc->IndexAccent4 = GetNLProcIndexAccent4(Template);
- return NLProc;
- }
-
-
- /* dispose of the nonlinear processor */
- void DisposeNLProcProcessor(NLProcRec* NLProc)
- {
- CheckPtrExistence(NLProc);
- ReleasePtr((char*)NLProc->WaveTableMatrix);
- NLProc->Next = NLProcFreeList;
- NLProcFreeList = NLProc;
- }
-
-
- /* update nonlinear state with accent information */
- void UpdateNLProcState(NLProcRec* NLProc, float Accent1, float Accent2,
- float Accent3, float Accent4)
- {
- float Temp;
-
- CheckPtrExistence(NLProc);
- /* multiply by NLProc->InverseVolume to undo the division everyone else does */
- NLProc->CurrentInputScaling = (NLProc->InputScaling + Accent1 * NLProc->InputAccent1
- + Accent2 * NLProc->InputAccent2 + Accent3 * NLProc->InputAccent3
- + Accent4 * NLProc->InputAccent4) * NLProc->InverseVolume;
- /* divide by NLProc->InverseVolume to restore the correct volume, and by */
- /* MAX16BIT to correct for value returned from wave index routine */
- NLProc->CurrentOutputScaling = (NLProc->OutputScaling + Accent1 * NLProc->OutputAccent1
- + Accent2 * NLProc->OutputAccent2 + Accent3 * NLProc->OutputAccent3
- + Accent4 * NLProc->OutputAccent4) / (NLProc->InverseVolume * MAX16BIT);
- Temp = NLProc->WaveTableIndex + Accent1 * NLProc->IndexAccent1
- + Accent2 * NLProc->IndexAccent2 + Accent3 * NLProc->IndexAccent3
- + Accent4 * NLProc->IndexAccent4;
- NLProc->CurrentWaveTableIndex = Double2FastFixed(Temp);
- }
-
-
- /* apply nonlinear processing to some stuff */
- void ApplyNLProc(largefixedsigned* Data, long NumFrames, NLProcRec* NLProc)
- {
- long Scan;
-
- CheckPtrExistence(Data);
- CheckPtrExistence(NLProc);
- if (NLProc->StereoFlag)
- {
- NumFrames *= 2;
- }
- for (Scan = 0; Scan < NumFrames; Scan += 1)
- {
- float Temp;
-
- PRNGCHK(Data,&(Data[Scan]),sizeof(Data[Scan]));
- Temp = (*NLProc->WaveIndexer)((1 + largefixed2single(Data[Scan])
- * NLProc->CurrentInputScaling) / 2 * (NLProc->FramesPerTable - 1),
- NLProc->CurrentWaveTableIndex,NLProc->NumberOfTables,
- NLProc->FramesPerTable,NLProc->WaveTableMatrix)
- * NLProc->CurrentOutputScaling;
- Data[Scan] = double2largefixed(Temp);
- }
- }
-